package com.qh.paythird.wxpay;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;

import javax.servlet.http.HttpServletRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.qh.common.utils.R;
import com.qh.pay.api.Order;
import com.qh.pay.api.PayConstants;
import com.qh.pay.api.constenum.OrderState;
import com.qh.pay.api.constenum.OutChannel;
import com.qh.paythird.wxpay.utils.HttpClientUtil;
import com.qh.paythird.wxpay.utils.UuidUtil;
import com.qh.paythird.wxpay.utils.WxPayResponseVo;
import com.qh.paythird.wxpay.utils.WxPayUtil;
import com.qh.paythird.wxpay.utils.XMLUtil;
import com.qh.redis.service.RedisUtil;

/**
 * 原生微信支付
 *
 */
@Service
public class WxPayService {


	private static final Logger logger = LoggerFactory.getLogger(WxPayService.class);
	
	/**
	 * @Description 微信发起
	 * @param order
	 * @return
	 */
	public R order(Order order) {
		logger.info("微信支付 开始------------------------------------------------------");
		try {
			if (OutChannel.wxpayqrcode.name().equals(order.getOutChannel())) { //微信扫码支付
				return orderWxpayQrCodePay(order);
			} else if (OutChannel.wxpayh5.name().equals(order.getOutChannel())) { //微信H5支付
				return orderWxpayH5Pay(order);
			} else{
				logger.error("支付宝支付 不支持的支付渠道：{}", order.getOutChannel());
				return R.error("不支持的支付渠道");
			}

		} finally {
			logger.info("微信支付 结束------------------------------------------------------");
		}
	}
	
     /*
	 * 微信扫码支付
	 * @param order
	 * @return
	 */
	private R orderWxpayQrCodePay(Order order){
		String merchantCode = order.getMerchNo();
		String orderId = merchantCode + order.getOrderNo();
		String payMerch = order.getPayMerch();
		
		String wxpay_gateway = RedisUtil.getPayCommonValue(payMerch+WxPayConst.wxpay_gateway);
		String wxpay_appId = RedisUtil.getPayCommonValue(WxPayConst.wxpay_appId);
		String wxpay_mchId = RedisUtil.getPayCommonValue(payMerch+ WxPayConst.wxpay_mchId);
		String wxpay_apiSecret = RedisUtil.getPayCommonValue(payMerch+WxPayConst.wxpay_apiSecret);
		String wxpay_appSecret = RedisUtil.getPayCommonValue(payMerch+WxPayConst.wxpay_appSecret);
		String wxpay_notifyurl = RedisUtil.getPayCommonValue(payMerch+WxPayConst.wxpay_notifyurl);
		String wxpay_openidurl = RedisUtil.getPayCommonValue(payMerch+WxPayConst.wxpay_openidurl);
		
		SortedMap<String, String> signParams = new TreeMap<String, String>();
        //付款类型为NATIVE
        String tradeType="NATIVE";
        signParams.put("trade_type", tradeType);
        //app_id
        signParams.put("appid", wxpay_appId);
        //微信商户账号
        signParams.put("mch_id", wxpay_mchId);
        
        //商品参数信息
        signParams.put("body", order.getTitle() );
        //32位不重复的编号
        signParams.put("nonce_str", UuidUtil.getUUID());
        //支付结果接收地址
        signParams.put("notify_url", wxpay_notifyurl);
        //订单编号
        signParams.put("out_trade_no",orderId);
        //支付金额 单位为分
        signParams.put("total_fee",String.valueOf(order.getAmount().multiply(new BigDecimal(100)).intValue()));
        //参数签名
        signParams.put("sign", WxPayUtil.createSign("UTF-8", signParams, wxpay_apiSecret));
        //生成Xml格式的字符串
        String requestXml = WxPayUtil.getRequestXml(signParams);
        //调用微信统一下单接口
        logger.info("微信支付创建预订单请求：{}", requestXml);
        WxPayResponseVo unifiedOrderVo = (WxPayResponseVo) XMLUtil.getObjectFromXML(HttpClientUtil.doPostXMl(wxpay_gateway, requestXml), WxPayResponseVo.class);
        logger.info("微信支付创建预订单返回：{}", JSON.toJSONString(unifiedOrderVo));


		Map<String, String> data = new HashMap<>();
		if ("success".equalsIgnoreCase(unifiedOrderVo.getReturn_code()) && "success".equalsIgnoreCase(unifiedOrderVo.getResult_code())) {
        	    data.put(PayConstants.web_qrcode_url, unifiedOrderVo.getCode_url());
        	    return R.okData(data);
        }else {
         	logger.error("微信二维码支付出错，错误原因："+JSON.toJSONString(unifiedOrderVo));
         	return R.error();
        }
	 }
	
	
    /*
	 * 微信h5支付
	 * @param order
	 * @return
	 */
	private R orderWxpayH5Pay(Order order){
		String merchantCode = order.getMerchNo();
		String orderId = merchantCode + order.getOrderNo();
		String payMerch = order.getPayMerch();
		
		String wxpay_gateway = RedisUtil.getPayCommonValue(payMerch+WxPayConst.wxpay_gateway);
		String wxpay_appId = RedisUtil.getPayCommonValue(WxPayConst.wxpay_appId);
		String wxpay_mchId = RedisUtil.getPayCommonValue(payMerch+ WxPayConst.wxpay_mchId);
		String wxpay_apiSecret = RedisUtil.getPayCommonValue(payMerch+WxPayConst.wxpay_apiSecret);
		String wxpay_appSecret = RedisUtil.getPayCommonValue(payMerch+WxPayConst.wxpay_appSecret);
		String wxpay_notifyurl = RedisUtil.getPayCommonValue(payMerch+WxPayConst.wxpay_notifyurl);
		String wxpay_openidurl = RedisUtil.getPayCommonValue(payMerch+WxPayConst.wxpay_openidurl);
		
	 
		SortedMap<String, String> signParams = new TreeMap<String, String>();
		//付款类型默认为H5支付
        String  tradeType = "JSAPI";
        signParams.put("trade_type", tradeType);
        signParams.put("openid", order.getUserId());
        
        //app_id
        signParams.put("appid", wxpay_appId);
        //微信商户账号
        signParams.put("mch_id", wxpay_mchId);
        
        //商品参数信息
        signParams.put("body", order.getTitle() );
        //32位不重复的编号
        signParams.put("nonce_str", UuidUtil.getUUID());
        //支付结果接收地址
        signParams.put("notify_url", order.getNotifyUrl());
        //订单编号
        signParams.put("out_trade_no", orderId );
        //支付金额 单位为分
        signParams.put("total_fee",String.valueOf(order.getAmount().multiply(new BigDecimal(100)).intValue()));
        //参数签名
        signParams.put("sign", WxPayUtil.createSign("UTF-8", signParams, wxpay_apiSecret));
        
        //生成Xml格式的字符串
        String requestXml = WxPayUtil.getRequestXml(signParams);
        //调用微信统一下单接口
        logger.info("微信支付创建预订单请求：{}", requestXml);
        WxPayResponseVo unifiedOrderVo = (WxPayResponseVo) XMLUtil.getObjectFromXML(HttpClientUtil.doPostXMl(wxpay_gateway, requestXml), WxPayResponseVo.class);
        logger.info("微信支付创建预订单返回：{}", JSON.toJSONString(unifiedOrderVo));
        
        Map<String, Object> data = new HashMap<>();
        SortedMap<String, String> result = new TreeMap<String, String>();
        if ("success".equalsIgnoreCase(unifiedOrderVo.getReturn_code()) && "success".equalsIgnoreCase(unifiedOrderVo.getResult_code())) {
            //默认支付类型是JSAPI
            result.put("appId", wxpay_appId);
            result.put("nonceStr", UuidUtil.getUUID() );
            result.put("package", "prepay_id=" + unifiedOrderVo.getPrepay_id());
            result.put("signType", "MD5");
            result.put("timeStamp", String.valueOf(System.currentTimeMillis() / 1000));
            result.put("paySign", WxPayUtil.createSign("UTF-8", signParams, wxpay_apiSecret));
            
            data.put("success",true);
			data.put("data", result);
			return R.okData(data);
        }else {
 		    data.put("success",false);
 		    data.put("msg", unifiedOrderVo.getErr_code_des());
 		   logger.error("微信H5支付出错，错误原因："+JSON.toJSONString(unifiedOrderVo));
 		    return R.error();
        }
	 }
	
	
	/**
	 * @Description 微信支付回调
	 * @param order
	 * @param request
	 * @return
	 */
	public R notify(Order order, HttpServletRequest request) {
		logger.info("微信支付异步通知开始-------------------------------------------------");
		
		/*String merchantCode = order.getMerchNo();
		String orderId = merchantCode + order.getOrderNo();
		String payMerch = order.getPayMerch();
		
		String wxpay_orderquery = RedisUtil.getPayCommonValue(payMerch+WxPayConst.wxpay_orderquery);
		String wxpay_appId = RedisUtil.getPayCommonValue(WxPayConst.wxpay_appId);
		String wxpay_mchId = RedisUtil.getPayCommonValue(payMerch+ WxPayConst.wxpay_mchId);
		String wxpay_apiSecret = RedisUtil.getPayCommonValue(payMerch+WxPayConst.wxpay_apiSecret);
		String wxpay_appSecret = RedisUtil.getPayCommonValue(payMerch+WxPayConst.wxpay_appSecret);
		String wxpay_notifyurl = RedisUtil.getPayCommonValue(payMerch+WxPayConst.wxpay_notifyurl);
		String wxpay_openidurl = RedisUtil.getPayCommonValue(payMerch+WxPayConst.wxpay_openidurl);
		
		
		Map<String, String> params = RequestUtils.getAllRequestParamStream(request);
        if (params.isEmpty()) {
            return null;
        }
        //订单号
        String out_trade_no = "";
        //订单应付金额
        String payAmount = "";
        //订单实收金额
        String receiptAmount = "";
        //订单实付金额
        String buyerPayAmount = "";
        //第三方平台订单号
        String transactionId = "";
        //业务状态码
        String resultCode = "";
        String openid = "";
        //支付场景参数
        String scene = "";
        String resultMsg = "";
        String payTime = "";
        String payCode = "";
        String tenpayCoupons = "";

        if (params.get("out_trade_no") != null) {
            out_trade_no = params.get("out_trade_no").toString();
        }
        if (params.get("total_fee") != null) {
            payAmount = params.get("total_fee").toString();
            receiptAmount = params.get("total_fee").toString();
        }
        if (params.get("settlement_total_fee") != null) {
            receiptAmount = params.get("settlement_total_fee").toString();
        }
        if (params.get("cash_fee") != null) {
            buyerPayAmount = params.get("cash_fee").toString();
        }
        if (params.get("transaction_id") != null) {
            transactionId = params.get("transaction_id").toString();
        }
        if (params.get("result_code") != null) {
            resultCode = params.get("result_code").toString();
        }
        if (params.get("openid") != null) {
            openid = params.get("openid").toString();
        }
        if (params.get("scene") != null) {
            scene = params.get("scene").toString();
        }
        if (params.get("err_code_des") != null) {
            resultMsg = params.get("err_code_des").toString();
        }
        if (params.get("payTime") != null) {
            payTime = params.get("payTime").toString();
        }
        if (params.get("payCode") != null) {
            payCode = params.get("payCode").toString();
        }
        if (params.get("tenpayCoupons") != null) {
            tenpayCoupons = params.get("tenpayCoupons").toString();
        }

        //封装返回结果
        SortedMap<String, String> resultMap = new TreeMap<>();
        resultMap.put("orderNo", out_trade_no);
        resultMap.put("tradeNo", transactionId);
        resultMap.put("payAmount", payAmount);
        resultMap.put("receiptAmount", receiptAmount);
        resultMap.put("buyerPayAmount", buyerPayAmount);
        resultMap.put("resultCode", resultCode);
        resultMap.put("resultMsg", resultMsg);
        resultMap.put("scene", scene);
        resultMap.put("openid", openid);
        resultMap.put("buyerId", openid);
        resultMap.put("payTime", payTime);
        resultMap.put("payCode", payCode);
        resultMap.put("tenpayCoupons", tenpayCoupons);

       //如果支付账号配置了apiKey，则添加签名
        resultMap.put("sign", NfPayUtil.createSign("UTF-8", resultMap));
        String response = HttpClientUtil.doPost(wxpay_notifyurl, params);*/
		return R.ok();
	}
	
	/**
	 * @Description 微信支付查询
	 * @param order
	 * @return
	 */
	public R query(Order order) {
		
		String merchantCode = order.getMerchNo();
		String orderId = merchantCode + order.getOrderNo();
		String payMerch = order.getPayMerch();
		
		String wxpay_orderquery = RedisUtil.getPayCommonValue(payMerch+WxPayConst.wxpay_orderquery);
		String wxpay_appId = RedisUtil.getPayCommonValue(WxPayConst.wxpay_appId);
		String wxpay_mchId = RedisUtil.getPayCommonValue(payMerch+ WxPayConst.wxpay_mchId);
		String wxpay_apiSecret = RedisUtil.getPayCommonValue(payMerch+WxPayConst.wxpay_apiSecret);
		String wxpay_appSecret = RedisUtil.getPayCommonValue(payMerch+WxPayConst.wxpay_appSecret);
		String wxpay_notifyurl = RedisUtil.getPayCommonValue(payMerch+WxPayConst.wxpay_notifyurl);
		String wxpay_openidurl = RedisUtil.getPayCommonValue(payMerch+WxPayConst.wxpay_openidurl);
		
		
		SortedMap<String, String> signParams = new TreeMap<String, String>();
        //app_id
        signParams.put("appid", wxpay_appId);
        //微信商户账号
        signParams.put("mch_id", wxpay_mchId);
        //商户订单号
        signParams.put("out_trade_no", orderId);
        //32位不重复的编号
        signParams.put("nonce_str", UuidUtil.getUUID());
        //参数签名
        signParams.put("sign", WxPayUtil.createSign("UTF-8", signParams, wxpay_apiSecret ));
        //生成Xml格式的字符串
        String requestXml = WxPayUtil.getRequestXml(signParams);
        //调用微信查询订单接口
        WxPayResponseVo queryOrderDTO;
        try {
        	    String json = HttpClientUtil.doPostXMl(wxpay_orderquery, requestXml, 3000);
            queryOrderDTO = (WxPayResponseVo) XMLUtil.getObjectFromXML(json, WxPayResponseVo.class);
        } catch (Exception e) {
            queryOrderDTO = new WxPayResponseVo();
            queryOrderDTO.setReturn_code("time_out");
            queryOrderDTO.setReturn_msg("查询超时");
        }
        
        String msg = "";
        if ("NOTPAY".equals(queryOrderDTO.getTrade_state())) {
	         //订单未支付
			 order.setOrderState(OrderState.fail.id());
			 msg = "订单未支付";
        }else if ("SUCCESS".equals(queryOrderDTO.getTrade_state())) {
	         //订单未支付
			 order.setOrderState(OrderState.succ.id());
			 msg = "支付成功";
       }else {
    	         //订单未支付
			 order.setOrderState(OrderState.fail.id());
			 msg = "订单未支付";
       }
       return R.ok(msg);
	}

}
